spb/search-box Public
Agentic web research engine — hypotheses, verbatim evidence, contradictions, sourced answers streamed live. Claude Opus 5 + Firecrawl + PostgreSQL.
TypeScript 76.9%
CSS 18.7%
SQL 2.1%
JavaScript 1.8%
Shell 0.5%
1/**2 * Search-box.ai3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File: apps/web/app/api/research/[id]/route.ts6 * Description: GET — full snapshot of a research session (state + citations).7 */89import { NextResponse } from "next/server";10import { sessions } from "@search-box/db";11import { ResearchState } from "@search-box/research";12import { ensureMigrated } from "@/lib/runner";1314export const runtime = "nodejs";15export const dynamic = "force-dynamic";1617export async function GET(18 _req: Request,19 { params }: { params: Promise<{ id: string }> }20): Promise<NextResponse> {21 await ensureMigrated();22 const { id } = await params;23 const session = await sessions.get(id);24 if (!session) return NextResponse.json({ error: "not found" }, { status: 404 });2526 const state = new ResearchState(id);27 const snap = await state.snapshot();28 const citations = snap.sources29 .filter((s) => s.citationIndex !== null)30 .sort((a, b) => (a.citationIndex ?? 0) - (b.citationIndex ?? 0))31 .map((s) => ({ index: s.citationIndex as number, sourceId: s.id, url: s.url, title: s.title }));3233 return NextResponse.json({ session, ...snap, citations });34}35